package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackStatMapper;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.album.service.TrackInfoService;
import com.atguigu.tingshu.album.service.VodService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.album.TrackStat;
import com.atguigu.tingshu.model.user.UserInfo;
import com.atguigu.tingshu.query.album.TrackInfoQuery;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.atguigu.tingshu.vo.album.*;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class TrackInfoServiceImpl extends ServiceImpl<TrackInfoMapper, TrackInfo> implements TrackInfoService {

	@Autowired
	private TrackInfoMapper trackInfoMapper;

	@Autowired
	private TrackStatMapper trackStatMapper;

	@Autowired
	private VodService vodService;

	@Autowired
	private AlbumInfoService albumInfoService;

	@Autowired
	private AlbumInfoMapper albumInfoMapper;

	@Autowired
	private UserInfoFeignClient userInfoFeignClient;


	@Override
	public void saveTrackInfo(TrackInfoVo trackInfoVo, Long userId) {
		//创建声音对象
		TrackInfo trackInfo = new TrackInfo();
		//属性拷贝
		BeanUtils.copyProperties(trackInfoVo, trackInfo);
		trackInfo.setStatus(SystemConstant.TRACK_STATUS_PASS);
		trackInfo.setUserId(userId);
		//获取上一条声音
		TrackInfo preTrackInfo = this.getOne(new LambdaQueryWrapper<TrackInfo>().eq(TrackInfo::getAlbumId,trackInfoVo.getAlbumId()).orderByDesc(TrackInfo::getId).select(TrackInfo::getOrderNum).last("limit 1"));
		int orderNum = 1;
		if(null != preTrackInfo){
			orderNum = preTrackInfo.getOrderNum() + 1;
		}
		//获取流媒体信息
		TrackMediaInfoVo trackMediaInfo = vodService.getTrackMediaInfo(trackInfoVo.getMediaFileId());
		//赋值排序值
		trackInfo.setOrderNum(orderNum);
		//赋值声音
		trackInfo.setMediaSize(trackMediaInfo.getSize());
		trackInfo.setMediaUrl(trackMediaInfo.getMediaUrl());
		trackInfo.setMediaDuration(trackMediaInfo.getDuration());
		trackInfo.setMediaType(trackMediaInfo.getType());

		this.save(trackInfo);
		//更新专辑声音总数
		AlbumInfo albumInfo = albumInfoService.getById(trackInfo.getAlbumId());
		int includeTrackCount = albumInfo.getIncludeTrackCount() + 1;
		albumInfo.setIncludeTrackCount(includeTrackCount);
		albumInfoService.updateById(albumInfo);
		//初始化统计数据
		this.saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_PLAY);
		this.saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_COLLECT);
		this.saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_PRAISE);
		this.saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_COMMENT);
	}

	/**
	 * 初始化统计数量
	 * @param trackId
	 * @param trackType
	 */
	private void saveTrackStat(Long trackId, String trackType) {
		TrackStat trackStat = new TrackStat();
		trackStat.setTrackId(trackId);
		trackStat.setStatType(trackType);
		trackStat.setStatNum(0);
		this.trackStatMapper.insert(trackStat);
	}

	@Override
	public IPage<TrackListVo> findUserTrackPage(Page<TrackListVo> trackListVoPage, TrackInfoQuery trackInfoQuery) {
		return trackInfoMapper.selectUserTrackPage(trackListVoPage,trackInfoQuery);
	}

	@Override
	public void removeTrackInfo(Long id) {
		//获取声音对象数据
		TrackInfo trackInfo = trackInfoMapper.selectById(id);
		//删除
		this.removeById(id);
		//更新专辑声音总数
		AlbumInfo albumInfo = this.albumInfoService.getById(trackInfo.getAlbumId());
		int includeTrackCount = albumInfo.getIncludeTrackCount() - 1;
		albumInfo.setIncludeTrackCount(includeTrackCount);
		albumInfoService.updateById(albumInfo);
		//删除统计数据
		trackStatMapper.delete(new LambdaQueryWrapper<TrackStat>().eq(TrackStat::getTrackId,id));
		//序号重新更新
		trackInfoMapper.updateTrackNum(trackInfo.getAlbumId(),trackInfo.getOrderNum());
		//删除声音媒体
		vodService.removeTrack(trackInfo.getMediaFileId());


	}

	@Override
	public void updateTrackInfo(Long id, TrackInfoVo trackInfoVo) {
		//获取声音对象
		TrackInfo trackInfo = this.getById(id);
		//获取传递的fileId
		String mediaFileId= trackInfoVo.getMediaFileId();
		//进行属性拷贝
		BeanUtils.copyProperties(trackInfoVo, trackInfo);
		//获取声音信息 页面传递的fileId与数据库的fileId不相等就修改
		if(!trackInfo.getMediaFileId().equals(mediaFileId)) {
			//说明已经修改过了
			TrackMediaInfoVo trackMediaInfoVo = vodService.getTrackMediaInfo(trackInfoVo.getMediaFileId());
			//判断对象不为空
			if(null==trackMediaInfoVo){
				throw new GuiguException(ResultCodeEnum.VOD_FILE_ID_ERROR);
			}
			trackInfo.setMediaUrl(trackMediaInfoVo.getMediaUrl());
			trackInfo.setMediaType(trackMediaInfoVo.getType());
			trackInfo.setMediaDuration(trackMediaInfoVo.getDuration());
			trackInfo.setMediaSize(trackMediaInfoVo.getSize());
			//删除云点播声音
			vodService.removeTrack(mediaFileId);
		}
		//修改数据
		this.updateById(trackInfo);
	}

	@Override
	public IPage<AlbumTrackListVo> findAlbumTrackPage(Page<AlbumTrackListVo> albumTrackListVoPage, Long albumId, Long userId) {
		/*
		1.选哟现根据专辑Id获取到声音列表
		2.判断用户是否登录
			null !=userId
			null == userId
			2.1.判断专辑类型
			2.2.除用户已购买声音得Id
		 */
		IPage<AlbumTrackListVo> albumTrackListVoIPage = trackInfoMapper.selectAlbumTrackList(albumTrackListVoPage,albumId);
		//查询专辑类型：
		AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
		//判断用户是否登录
		if(null==userId){
			if(!SystemConstant.ALBUM_PAY_TYPE_FREE.equals(albumInfo.getPayType())) {
				//免费试听集数:5集
				Integer tracksForFree = albumInfo.getTracksForFree();
				//除免费试听声音都需要付费
				albumTrackListVoIPage.getRecords().stream().filter(albumTrackListVo -> albumTrackListVo.getOrderNum() > tracksForFree).forEach(albumTrackListVo -> albumTrackListVo.setIsShowPaidMark(true));
			}
		}else{
			//获取用户信息
			Result<UserInfoVo> userInfoVoResult = userInfoFeignClient.getUserInfoVo(userId);
			Assert.notNull(userInfoVoResult,"查询用户信息失败");
			UserInfoVo userInfoVo = userInfoVoResult.getData();
			Assert.notNull(userInfoVo,"查询用户信息失败");
			//设置一个变量,记录是否需要付费, false :免费  true:付费
			boolean isPaid = false;
			//判断专辑类型，vip;免费
			if(SystemConstant.ALBUM_PAY_TYPE_VIPFREE.equals(albumInfo.getPayType())){
				// 用户是Vip，但是已经过期
				if((userInfoVo.getIsVip()==1 && userInfoVo.getVipExpireTime().before(new Date())) || userInfoVo.getIsVip()==0){
					//需要付费
					isPaid = true;
				}
			} else if (SystemConstant.ALBUM_PAY_TYPE_REQUIRE.equals(albumInfo.getPayType())) {
				//必须付费
				isPaid = true;
			}

			if(isPaid){
				//远程调用，需要知道用户购买了哪些声音，专辑Id，付费声音列表;userId--从本地线程中获取
				List<AlbumTrackListVo> albumTrackListVoList = albumTrackListVoIPage.getRecords().stream().filter(albumTrackListVo -> albumTrackListVo.getOrderNum() > albumInfo.getTracksForFree()).collect(Collectors.toList());
				//这个是付费声音Id
				List<Long> trackIdList = albumTrackListVoList.stream().map(AlbumTrackListVo::getTrackId).collect(Collectors.toList());
				//获取用户购买得声音列表,如果购买了，将购买得声音Id与状态存储到map集合中，map.put（trackId，1）
				Result<Map<Long, Integer>> mapResult = userInfoFeignClient.userIsPaidTrack(albumId, trackIdList);
				Assert.notNull(mapResult,"查询用户购买声音失效");
				Map<Long, Integer> map = mapResult.getData();
				//map.put(trackId,1)-买过,map.put(trackId,0)-没买过
				for(AlbumTrackListVo albumTrackListVo : albumTrackListVoList){
					albumTrackListVo.setIsShowPaidMark(map.get(albumTrackListVo.getTrackId())==0);
				}
			}
		}
		return albumTrackListVoIPage;
	}

	@Override
	public void updateTrackStat(TrackStatMqVo trackStatMqVo) {
		//1.更新声音的播放量
		//判断是否是属于播放量
		if(SystemConstant.TRACK_STAT_PLAY.equals(trackStatMqVo.getStatType())){
			//调用更新方法
			trackInfoMapper.updateTrackStat(trackStatMqVo.getCount(),trackStatMqVo.getTrackId(),trackStatMqVo.getStatType());
			//更新专辑播放量
			albumInfoMapper.updateAlbumStat(trackStatMqVo.getCount(),trackStatMqVo.getTrackId(),SystemConstant.ALBUM_STAT_PLAY);
		}else if (SystemConstant.TRACK_STAT_COLLECT.equals(trackStatMqVo.getStatType())){

		}
	}

	@Override
	public List<Map<String, Object>> findUserTrackPaidList(Long trackId, Long userId) {
		/*
		1.从当前电机的声音开始，巨酸有多少需要付费的声音列表；
		2.查询用户是否购买过当前专辑对应的声音，然后与1步骤进行过滤
		 */
		List<Map<String,Object>> list = new ArrayList<>();
		//获取对象
		TrackInfo trackInfo = this.getById(trackId);
		//获取当前声音Id的排序值
		Integer orderNum = trackInfo.getOrderNum();
		//获取到当前用户购买的声音列表
		Result<List<Long>> trackIdListResult = userInfoFeignClient.findUserPaidTrackList(trackInfo.getAlbumId());
		Assert.notNull(trackIdListResult,"查询用户购买声音列表失败");
		List<Long> trackIdList = trackIdListResult.getData();

		//从当前声音Id开始计算有多少声音是需要付费的集合Id
		List<TrackInfo> trackInfoList = trackInfoMapper.selectList(new LambdaQueryWrapper<TrackInfo>()
				.eq(TrackInfo::getAlbumId, trackInfo.getAlbumId())
				.gt(TrackInfo::getOrderNum, orderNum));
		//两个集合取差集，需要付费的声音列表
		List<TrackInfo> paidTrackIdList = trackInfoList.stream().filter(trackInfoItem -> !trackIdList.contains(trackInfoItem.getId())).collect(Collectors.toList());
		//根据专辑Id获取专辑对象
		AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfo.getAlbumId());
		//判断
		if(paidTrackIdList.size() >= 0){
			//限显示本集
			HashMap<String,Object> map = new HashMap<>();
			map.put("name","本集");
			//当前每一集声音的价格
			map.put("price",albumInfo.getPrice());
			map.put("trackCount",0);
			list.add(map);
		}
		//后9集
		if(paidTrackIdList.size()>0 && paidTrackIdList.size()<=10){
			//显示后size集
			HashMap<String,Object> map = new HashMap<>();
			map.put("name","后"+paidTrackIdList.size()+"集");
			//当前每一集声音的价格
			map.put("price",albumInfo.getPrice().multiply(new BigDecimal(String.valueOf(paidTrackIdList.size()))));
			map.put("trackCount",paidTrackIdList.size());
			//添加到集合
			list.add(map);
		}
		//后10集
		if(paidTrackIdList.size() > 10){
			//后十集集合
			HashMap<String,Object> map = new HashMap<>();
			map.put("name","后10集");
			//当前每一集声音的钱数
			map.put("price",albumInfo.getPrice().multiply(new BigDecimal("10")));
			map.put("trackCount",10);
			//添加到集合
			list.add(map);
		}
		//后20集
		if(paidTrackIdList.size()>10 && paidTrackIdList.size()<=20){
			//显示后size集
			HashMap<String,Object> map = new HashMap<>();
			map.put("name","后"+paidTrackIdList.size()+"集");
			//当前每一集声音的价格
			map.put("price",albumInfo.getPrice().multiply(new BigDecimal(String.valueOf(paidTrackIdList.size()))));
			map.put("trackCount",paidTrackIdList.size());
			//添加到集合
			list.add(map);
		}
		//后19集
		if(paidTrackIdList.size() > 20){
			//后19集集合
			HashMap<String,Object> map = new HashMap<>();
			map.put("name","后20集");
			//当前每一集声音的钱数
			map.put("price",albumInfo.getPrice().multiply(new BigDecimal("20")));
			map.put("trackCount",20);
			//添加到集合
			list.add(map);
		}

		return list;
	}

	@Override
	public List<TrackInfo> findPaidTrackInfoList(Long trackId, Integer trackCount, Long userId) {
		//声明一个集合
		List<TrackInfo> trackInfoList = new ArrayList<>();
		//1.获取用户购买过的声音列表
		//通过声音Id获取到声音对象中的专辑Id
		TrackInfo trackInfo = this.getById(trackId);
		Result<List<Long>> userPaidTrackList = userInfoFeignClient.findUserPaidTrackList(trackInfo.getAlbumId());
		//判断返回数据集
		Assert.notNull(userPaidTrackList,"查询用户购买声音列表失败");
		//这个集合可以为空
		List<Long> userPaidTrackIdList = userPaidTrackList.getData();
		//判断当前购买的集数
		if(0 == trackCount){
			trackInfoList.add(trackInfo);
		}else {
			//设置查询条件
			LambdaQueryWrapper<TrackInfo> wrapper = new LambdaQueryWrapper<>();
			wrapper.gt(TrackInfo::getOrderNum, trackInfo.getOrderNum())
					.eq(TrackInfo::getAlbumId, trackInfo.getAlbumId());
			if (!CollectionUtils.isEmpty(userPaidTrackIdList)) {
				//排除已购买的声音id
				wrapper.notIn(TrackInfo::getId, userPaidTrackIdList);
			}
			wrapper.last(" limit " + trackCount);
			//查询数据
			trackInfoList = trackInfoMapper.selectList(wrapper);
		}

		return trackInfoList;
	}


}
